﻿using System;
using System.Data.Common;
using DuckDB.NET.Data;

namespace RPAAction.Data_CSO
{
    public class DuckDbDataExport : RPADataExport
    {
        public DuckDbDataExport(string dbPath, string table)
        {
            connection = new DuckDBConnection($"Data Source={dbPath};");
            connection.Open();
            tableName = table;
        }

        protected override void Close()
        {
            if (appender != null)
            {
                appender.Close();
                appender.Dispose();
            }
            if (connection != null)
            {
                connection.Close();
                connection.Dispose();
            }
        }

        protected override void CreateTable(DbDataReader r)
        {
            Exception sqlE = null;
            try
            {
                string sql = GetCreateTableString(r, "VARCHAR", "\"", "\"", "CREATE TABLE IF NOT EXISTS ");
                using (var command = connection.CreateCommand())
                {
                    command.CommandText = sql;
                    command.ExecuteNonQuery();
                }
            }
            catch (Exception e)
            {
                sqlE = e;
                throw;
            }
            finally
            {
                try
                {
                    appender = connection.CreateAppender(tableName);
                    row = appender.CreateRow();
                }
                catch (Exception)
                {
                    throw new Base.ActionException($"创建表[{tableName}]失败,详情如下:\n{sqlE ?? new Exception("")}");
                }
            }
        }

        protected override void SetValue(string field, object value)
        {
            if (value is null)
            {
                row.AppendNullValue();
            }
            else if (value is bool b)
            {
                row.AppendValue(b);
            }
            else if (value is string s)
            {
                row.AppendValue(s);
            }
            else if (value is sbyte sb)
            {
                row.AppendValue(sb);
            }
            else if (value is short sh)
            {
                row.AppendValue(sh);
            }
            else if (value is int i)
            {
                row.AppendValue(i);
            }
            else if (value is long l)
            {
                row.AppendValue(l);
            }
            else if (value is byte bt)
            {
                row.AppendValue(bt);
            }
            else if (value is ushort ush)
            {
                row.AppendValue(ush);
            }
            else if (value is uint ui)
            {
                row.AppendValue(ui);
            }
            else if (value is ulong ul)
            {
                row.AppendValue(ul);
            }
            else if (value is float f)
            {
                row.AppendValue(f);
            }
            else if (value is double d)
            {
                row.AppendValue(d);
            }
            else if (value is DateTime dt)
            {
                row.AppendValue(dt);
            }
            else
            {
                row.AppendValue(value.ToString());
            }
        }

        protected override void UpdataRow()
        {
            row.EndRow();
            row = appender.CreateRow();
        }

        private DuckDBConnection connection;
        private DuckDBAppender appender;
        private DuckDBAppenderRow row;
    }
}
